package pt.inescid.components.policyengine.heimdall.pap.base;

import java.util.Vector;

import pt.inescid.components.policyengine.heimdall.commons.Utilities;

public class PolicyDefinition {

	public static final int RELEVANCE_SECTION = 0;
	public static final int DECISION_SECTION = 1;

	public static final int REEVAL_START_SECTION = 2;
	public static final int REEVAL_STOP_SECTION = 3;

	public static final int CES_RESTRICTION_SECTION = 4;
	public static final int CES_PURGE_SECTION = 5;

	private String name;
	private Vector quantifiers;
	private RuleDefinition relevance;
	private RuleDefinition authorization;
	private boolean isRemote;

	public PolicyDefinition(String name) {
		this(name, false);
	}
	
	public PolicyDefinition(String name, boolean isRemote) {
		this.name = name;
		quantifiers = new Vector();
		this.isRemote = isRemote;
	}
	
	public void addExpression(RuleDefinition newExpression,	RuleDefinition previousLevelExp, int policySection) {
		
		if (previousLevelExp == null) {
			if (policySection == RELEVANCE_SECTION) {
				relevance = newExpression;
			}
			else {
				authorization = newExpression;
			}
		}
		else if (previousLevelExp.getType() == RuleDefinition.CES_SUM_EXPRESSION) {
			((CesAggDefinition) previousLevelExp).addEventField(
					(EventFieldDefinition) newExpression);
		}
		else {
			((CompositeDefinition) previousLevelExp).addOperand(newExpression);
		}	
	}

	public void addQuantifier(QuantifierDefinition newQuant) {
		quantifiers.add(newQuant);
	}


	public RuleDefinition getAuthorization() {
		return authorization;
	}


	public String getName() {
		return name;
	}

	public String getCapitalizedName() {
		return (name.substring(0,1).toUpperCase() + name.substring(1));
	}


	public RuleDefinition getRelevance() {
		return relevance;
	}


	public void setAuthorization(RuleDefinition authorization) {
		this.authorization = authorization;
	}


	public void setName(String name) {
		this.name = name;
	}


	public void setRelevance(RuleDefinition relevance) {
		this.relevance = relevance;
	}
	
//  ----------------------------------------------------------
//  ------------------------   toString   ------------------------
//  ----------------------------------------------------------
	public String toString() {
		String result = "\n";
		
		result += "Policy: " + name + "\n";
		
		for (int i = 0; i < quantifiers.size(); i++) {
			result += "Qt: " + 
			((QuantifierDefinition) quantifiers.elementAt(i)) + 
			"\n";
		}
		result += "Relevance: " + relevance + "\n";
		result += "Decision: " + authorization + "\n";
		
		return (result);
	}

	//  ----------------------------------------------------------
//  ------------------------   getFunction   ------------------------
//  ----------------------------------------------------------
	public String getFunction() {
		String result = "";
		
		result += "Policy: " + name + "\n";
		
		for (int i = 0; i < quantifiers.size(); i++) {
			result += "Qt: " + 
			((QuantifierDefinition) quantifiers.elementAt(i)) + 
			"\n";
		}
		result += "Relevance: " + relevance.getFunction() + "\n";
		result += "Decision: " + authorization.getFunction() + "\n";
		
		return (result);
	}

	public Vector getQuantifiers() {
		return quantifiers;
	}

//  ----------------------------------------------------------
//  ------------------------   isPolicyComposition   ------------------------
//  ----------------------------------------------------------
	public boolean isPolicyComposition() {
		if (authorization == null) {
			return (false);
		}
		else {
			return (authorization.isPolicyComposition());
		}
	}

//  ----------------------------------------------------------
//  ------------------------   getRelevantEventFields   ------------------------
//  ----------------------------------------------------------
	public Vector getRelevantEventFields() {
		Vector allRelevant = new Vector();
		Vector currentRelevant = null;
		
		if (relevance != null) {
			currentRelevant = relevance.getRelevantEventFields();
			Utilities.joinParametersNoDuplicates(allRelevant, currentRelevant);
		}
		
		if (authorization != null) {
			currentRelevant = authorization.getRelevantEventFields();
			Utilities.joinParametersNoDuplicates(allRelevant, currentRelevant);
		}
		
		return (allRelevant);
	} // getRelevantEventFields

	
	
//  ----------------------------------------------------------
//  ------------------------   getRelevantCes   ------------------------
//  ----------------------------------------------------------
	public Vector getRelevantCes() {
		Vector allRelevant = new Vector();
		Vector currentRelevant = null;
		
		QuantifierDefinition currentQt = null;
		for (int i = 0; i < quantifiers.size(); i++) {
			System.out.println("ENTROU!!!!!");
			currentQt = (QuantifierDefinition)
					quantifiers.elementAt(i);
			currentRelevant = new Vector();
			currentRelevant.add(currentQt.getCes());
			Utilities.joinCesNoDuplicates(allRelevant, currentRelevant);
		}
		
		if (relevance != null) {
			currentRelevant = relevance.getRelevantCes();
			Utilities.joinCesNoDuplicates(allRelevant, currentRelevant);
		}
		
		if (authorization != null) {
			currentRelevant = authorization.getRelevantCes();
			Utilities.joinCesNoDuplicates(allRelevant, currentRelevant);
		}
		
		return (allRelevant);
	} // getRelevantCes

	
//  ----------------------------------------------------------
//  ------------------------   keepOnlyThisCes   ------------------------
//  ----------------------------------------------------------
	public void keepOnlyThisCes(String cesName) {
		relevance = relevance.keepOnlyThisCes(cesName);
		authorization = authorization.keepOnlyThisCes(cesName);
	} // keepOnlyThisCes

	
	public boolean isRemote() {
		return isRemote;
	}

	public void setRemote(boolean isRemote) {
		this.isRemote = isRemote;
	}

	/* ===========================================================
	==============================================================
	=============                    =============================
	=============      isObligation       =============================
	=============                    =============================
	==============================================================
	=========================================================== */
	public boolean isObligation() {
		QuantifierDefinition currentQt = null;
		for (int i = 0; i < quantifiers.size(); i++) {
			currentQt = (QuantifierDefinition)
					quantifiers.elementAt(i);
			
			if (currentQt.isObligation()) {
				
				return (true);
			}
		}
		
		return (false);
	}
	
	/* ===========================================================
	==============================================================
	=============                    =============================
	=============      getObligationTimeout       =============================
	=============                    =============================
	==============================================================
	=========================================================== */
	public long getObligationTimeout() {
		QuantifierDefinition currentQt = null;
		long maxTimeout = 0;
		for (int i = 0; i < quantifiers.size(); i++) {
			currentQt = (QuantifierDefinition)
					quantifiers.elementAt(i);
			
			if (currentQt.getWithinMilli() > maxTimeout) {
				maxTimeout = currentQt.getWithinMilli();
			}
		}
		
		return (maxTimeout);
	}
	
}; // PolicyDefinition
